﻿using System;
using System.Reflection;
using System.Windows.Forms;
using OpenTK;
using Painter3D.RenderSys;

namespace Painter3D.DebugForm
{
    public partial class DebugForm : Form
    {
        private Transform traget;

        public DebugForm()
        {
            InitializeComponent();
            TragetValueFeedBack = TransformFeedBack;
        }

        #region 参数反射
        private void ClassRefelection(Type classType)
        {
            PropertyInfo[] properties = classType.GetProperties(BindingFlags.Instance | BindingFlags.Public);
            foreach (var property in properties)
            {
                Console.WriteLine(property.Name + ":" + property.PropertyType.Name);
            }
            FieldInfo[] fields = classType.GetFields(BindingFlags.CreateInstance | BindingFlags.Public);
            foreach (var field in fields)
            {
                Console.WriteLine(field.Name + ":" + field.FieldType.Name);
            }
        }
        #endregion

        #region 节点树
        private void buttonReload_Click(object sender, EventArgs e)
        {
            transformTreeViewer.Nodes.Clear();
            Transform.WorldTransform.LoopTreeWithF((transform, layer) =>
            {
                TreeNodeCollection nodes = transformTreeViewer.Nodes;
                for (int i = 0; i < layer; i++)
                {
                    nodes = nodes[nodes.Count - 1].Nodes;
                }
                nodes.Add(transform.Name);
                return false;
            }, 0);
            transformTreeViewer.ExpandAll();
        }
        private void transformTreeViewer_AfterSelect(object sender, TreeViewEventArgs e)
        {
            Transform transform = Transform.FindByPath(transformTreeViewer.SelectedNode.FullPath);
            if (transform != null)
            {
                traget = transform;
                TragetValueFeedBack();
            }
            else
            {
                MessageBox.Show("Transform lost");
            }
        }
        #endregion

        #region 变换操作
        private void TransformFeedBack()
        {
            EnableChange = false;
            if (traget != null)
            {
                Quaternion q = traget.quaternion;
                trackBarX.Value = (int)Math.Atan2(2 * (q.W * q.X + q.Y * q.Z), 1 - 2 * (q.X * q.X + q.Y * q.Y));
                trackBarY.Value = (int)Math.Acos(2 * (q.W * q.Y - q.Z * q.X));
                trackBarZ.Value = (int)Math.Atan2(2 * (q.W * q.Z + q.X * q.Y), 1 - 2 * (q.Y * q.Y + q.Z * q.Z));

                TranslateTextX.Text = traget.position.X.ToString();
                TranslateTextY.Text = traget.position.Y.ToString();
                TranslateTextZ.Text = traget.position.Z.ToString();
            }
            EnableChange = true;
        }

        private void TranslateChange(object sender, EventArgs e)
        {
            if (!EnableChange)
                return;
            if (float.TryParse(TranslateTextX.Text, out float x)
                && float.TryParse(TranslateTextY.Text, out float y)
                && float.TryParse(TranslateTextZ.Text, out float z)
                && traget != null)
            {
                traget.position = new Vector3(x, y, z);
                MessageLable.Text = traget.Name + "移动到(" + x + "," + y + "," + z + ")";
            }
            else
            {
                MessageLable.Text = "未选定变换目标或输入格式错误，平移变换请输入数字";
            }
        }

        private void RotateChange(object sender, EventArgs e)
        {
            if (!EnableChange)
                return;
            if (traget != null)
            {
                float x = trackBarX.Value / 180.0f * (float)Math.PI;
                float y = trackBarY.Value / 180.0f * (float)Math.PI;
                float z = trackBarZ.Value / 180.0f * (float)Math.PI;
                traget.quaternion = Quaternion.FromEulerAngles(x, y, z);
                MessageLable.Text = traget.Name + "旋转到到(" + x + "," + y + "," + z + ")";
            }
            else
            {
                MessageLable.Text = "未选定变换目标";
            }
        }

        #endregion

        #region 材质操作

        private void MaterialFeedback()
        {
            EnableChange = false;

            if (traget != null)
            {
                Render render = traget.GetComponent<Render>();
                if (render != null)
                    labelShaderName.Text = "着色器名称:" + render.Material.shader.shaderName;

            }
            EnableChange = true;
        }

        #endregion

        #region 数据更新
        private Action TragetValueFeedBack;
        /// <summary>
        /// 避免反馈数据时触发修改函数
        /// </summary>
        private bool EnableChange = true;
        private void tabControlMain_SelectedIndexChanged(object sender, EventArgs e)
        {
            switch (tabControlMain.SelectedIndex)
            {
                case 0:
                    TragetValueFeedBack = TransformFeedBack;
                    break;
                case 1:
                    TragetValueFeedBack = MaterialFeedback;
                    break;
                default:
                    break;
            }
            TragetValueFeedBack();
        }

        /// <summary>
        /// 控制左下角的信息面板
        /// </summary>
        private void FeedBack(object sender, EventArgs e)
        {
            if (traget != null)
            {
                textBoxInfo.Text = $"{traget.Name}{Environment.NewLine}Transform->{Environment.NewLine}Position:{traget.position}{Environment.NewLine}Rotation:{traget.quaternion}{Environment.NewLine}{$"{(traget.Enable ? "Enable" : "Disable")}{Environment.NewLine}{(traget.UserVisable ? " Visable" : "SystemNode")}{Environment.NewLine}"}";
                foreach (var component in traget.components)
                {
                    textBoxInfo.Text += component.ToString();
                }
            }
        }
        #endregion
    }
}
